From: Joan Torres Date: Wed, 7 Feb 2024 12:05:17 +0000 (+0100) Subject: loginDialog: On login, allow logout a conflicting session X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~281^2~1^2~51 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=df84854d9073c457d79d7c2e6a5750428c52ff01;p=gnome-shell.git loginDialog: On login, allow logout a conflicting session When opening a session, find if there's already a session opened for the same user with the help of Loginmanager. When it's found, display the conflicting session dialog. The logout dialog allows shutting down the conflicting session using the greeter dbus method "StopConflictingSession". If the dialog is already opened and the conflicting session has been closed on its side, the new session will start. Part-of: --- diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js index 09b68b42f..c0ded7506 100644 --- a/js/gdm/loginDialog.js +++ b/js/gdm/loginDialog.js @@ -1071,6 +1071,30 @@ export const LoginDialog = GObject.registerClass({ }, this); } + _showConflictingSessionDialog(serviceName, conflictingSession) { + let conflictingSessionDialog = new ConflictingSessionDialog(conflictingSession, + this._greeterSessionProxy, + this._user.get_user_name()); + + conflictingSessionDialog.connect('cancel', () => { + this._authPrompt.reset(); + conflictingSessionDialog.close(); + }); + conflictingSessionDialog.connect('force-stop', () => { + this._greeter.call_stop_conflicting_session_sync(null); + }); + + const loginManager = LoginManager.getLoginManager(); + loginManager.connectObject('session-removed', (lm, sessionId) => { + if (sessionId === conflictingSession.Id) { + conflictingSessionDialog.close(); + this._authPrompt.finish(() => this._startSession(serviceName)); + } + }, conflictingSessionDialog); + + conflictingSessionDialog.open(); + } + _startSession(serviceName) { this._bindOpacity(); this.ease({ @@ -1084,7 +1108,40 @@ export const LoginDialog = GObject.registerClass({ }); } - _onSessionOpened(client, serviceName) { + async _findConflictingSession(ignoreSessionId) { + const userName = this._user.get_user_name(); + const loginManager = LoginManager.getLoginManager(); + const sessions = await loginManager.listSessions(); + for (const session of sessions.map(([id, , user, , path]) => ({id, user, path}))) { + if (ignoreSessionId === session.id) + continue; + + if (userName !== session.user) + continue; + + const sessionProxy = loginManager.getSession(session.path); + + if (sessionProxy.Type !== 'wayland' && sessionProxy.Type !== 'x11') + continue; + + if (sessionProxy.State !== 'active' && sessionProxy.State !== 'online') + continue; + + return sessionProxy; + } + + return null; + } + + async _onSessionOpened(client, serviceName, sessionId) { + if (sessionId) { + const conflictingSession = await this._findConflictingSession(sessionId); + if (conflictingSession) { + this._showConflictingSessionDialog(serviceName, conflictingSession); + return; + } + } + this._authPrompt.finish(() => this._startSession(serviceName)); }